package interactiond

import (
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/common"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/ddd"
)

const (
	// Interaction 互动标识
	Interaction = "interaction"
)

var (
	_ InteractionAggregateRoot = &interactionAggregateRoot{}
)

func initInteraction(d ddd.Domain, repo InteractionRepo) {
	ar := &interactionAggregateRoot{}
	ar.Init(ar, d, Interaction)
	repo.Init(repo, ar, Interaction)
}

// InteractionAggregateRoot 互动的聚合根
type InteractionAggregateRoot interface {
	ddd.AggregateRoot
	// 新增互动
	AddInteraction(ctx ddd.Context, interaction InteractionDesc) (id string, err error)
	// 获取指定互动：根据唯一标识获取互动实体
	GetInteraction(ctx ddd.Context, id string) (ia *InteractionAggregate, err error)
	// 分页获取互动列表：根据唯一标识获取下一页指定数量的互动实体集合
	QueryPage(ctx ddd.Context, is InteractionSearch, pi common.PageInfo) (pr common.PageResult, result []InteractionAggregate, err error)
	QueryGroupInteractionPage(ctx ddd.Context, igid string, code []string, pi common.PageInfo) (pr common.PageResult, result []InteractionAggregate, err error)
	// 查询匹配数量
	QueryNum(ctx ddd.Context, is InteractionSearch) (num int, err error)
}

// InteractionRepo 互动仓储
type InteractionRepo interface {
	ddd.Repository
	// 新增互动
	AddInteraction(ctx ddd.Context, interaction InteractionDesc) (id string, err error)
	// 获取指定互动：根据唯一标识获取互动实体
	GetInteraction(ctx ddd.Context, interactionid string) (*InteractionAggregate, error)
	// 分页获取互动列表：根据唯一标识获取下一页指定数量的互动实体集合
	// total 总数量
	QueryPage(ctx ddd.Context, is InteractionSearch, pi common.PageInfo) (pr common.PageResult, result []InteractionAggregate, err error)
	// 修改互动 值
	UpdateValue(ctx ddd.Context, interactionid string, value int) error
	// 删除互动 标记删除
	Delete(ctx ddd.Context, interactionid string) error
	// 彻底删除指定互动
	Destroy(ctx ddd.Context, interactionid string) error
	// 查询匹配数量
	QueryNum(ctx ddd.Context, is InteractionSearch) (num int, err error)
}

// InteractionSearch 查询条件
type InteractionSearch struct {
	Codes []string `json:"codes,omitempty"` // 查询条件
	IGID  []string `json:"igid,omitempty"`  // 互动组编号
	UID   []string `json:"uid,omitempty"`   // 互动用户
}

// InteractionAggregate 互动聚合
type InteractionAggregate struct {
	ddd.BaseAggregate
	InteractionID string `json:"interaction_id"` // 互动ID

	InteractionDesc `json:"interaction_desc"` // 互动描述值对象
	Operator        `json:"operator"`         // 操作者值对象
}

// Repo 获取聚合根对应的仓储
func (i *InteractionAggregate) Repo() InteractionRepo {
	return i.Repository().(InteractionRepo)
}

// UpdateValue 修改互动聚合中的互动值
func (i *InteractionAggregate) UpdateValue(ctx ddd.Context, value int) error {
	err := i.Repo().UpdateValue(ctx, i.InteractionID, value)
	if err != nil {
		return err
	}
	ni, _ := i.Repo().GetInteraction(ctx, i.InteractionID)
	old := *i
	i.Trigger(ctx, EvtTypInteraction, EvtActUpdateValue, map[string]interface{}{
		"old": &old,
		"new": ni,
	})
	return err
}

// Delete 删除互动聚合
func (i *InteractionAggregate) Delete(ctx ddd.Context) error {
	old := *i
	err := i.Repo().Delete(ctx, i.InteractionID)
	if err != nil {
		return err
	}
	i.Trigger(ctx, EvtTypInteraction, EvtActDelete, &old)
	return err
}

// Destroy 彻底删除互动聚合
func (i *InteractionAggregate) Destroy(ctx ddd.Context) error {
	err := i.Repo().Destroy(ctx, i.InteractionID)
	if err != nil {
		return err
	}
	i.Trigger(ctx, EvtTypInteraction, EvtActDestroy, i.InteractionDesc)
	return err
}

type interactionAggregateRoot struct {
	ddd.BaseAggregateRoot
}

func (i *interactionAggregateRoot) Repo() InteractionRepo {
	return i.Repository().(InteractionRepo)
}
func (i *interactionAggregateRoot) AddInteraction(ctx ddd.Context, interaction InteractionDesc) (id string, err error) {
	id, err = i.Repo().AddInteraction(ctx, interaction)
	if err != nil {
		return
	}
	i.Trigger(ctx, EvtTypInteraction, EvtActAdd, id)
	return
}
func (i *interactionAggregateRoot) GetInteraction(ctx ddd.Context, id string) (ia *InteractionAggregate, err error) {
	return i.Repo().GetInteraction(ctx, id)
}

// 分页获取互动列表：根据唯一标识获取下一页指定数量的互动实体集合
// total 总数量
func (i *interactionAggregateRoot) QueryPage(ctx ddd.Context, is InteractionSearch, pi common.PageInfo) (common.PageResult, []InteractionAggregate, error) {
	return i.Repo().QueryPage(ctx, is, pi)
}
func (i *interactionAggregateRoot) QueryGroupInteractionPage(ctx ddd.Context, igid string, code []string, pi common.PageInfo) (pr common.PageResult, result []InteractionAggregate, err error) {
	return i.Repo().QueryPage(ctx, InteractionSearch{IGID: []string{igid}, Codes: code}, pi)
}

// 查询匹配数量
func (i *interactionAggregateRoot) QueryNum(ctx ddd.Context, is InteractionSearch) (num int, err error) {
	return i.Repo().QueryNum(ctx, is)
}
